package com.ruoyi.common.utils;

import io.minio.*;
import io.minio.errors.*;
import io.minio.http.Method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.management.openmbean.InvalidKeyException;
import java.io.IOException;
import java.io.InputStream;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class MinioUtil {
    @Resource
    private MinioClient minioClient;
    @Value("${minio.bucket-name}")
    private String bucketName;

    public void createBucket(String bucketName) {
        BucketExistsArgs bucketExistsArgs = BucketExistsArgs.builder().bucket(bucketName).build();
        MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(bucketName).build();
        try {
            if (minioClient.bucketExists(bucketExistsArgs)) {
                return;
            }
            minioClient.makeBucket(makeBucketArgs);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }


    public ObjectWriteResponse putObject(MultipartFile file, String objectName, String contentType) {
        try {
            //调用创建桶方法
            createBucket(bucketName);
            //获取文件输入流
            InputStream inputStream = file.getInputStream();
            PutObjectArgs args = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .contentType(contentType)
                    .stream(inputStream, inputStream.available(), -1)
                    .build();
            return minioClient.putObject(args);
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | XmlParserException |
                 java.security.InvalidKeyException | io.minio.errors.ServerException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取⽂件外链
     *
     * @param bucketName bucket名称
     * @param objectName ⽂件名称
     * @param expires    过期时间 <=7
     * @param timeUnit 有效期时间单位
     */
    public String getObjectUrl(String bucketName, String objectName, Integer expires, TimeUnit timeUnit) {
        GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(bucketName)
                .object(objectName)
                .expiry(expires,timeUnit)// 单位：默认是，秒
                .build();
        try {
            String url=minioClient.getPresignedObjectUrl(args);
            return getImgUrl(url);
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidResponseException |
                 InvalidKeyException | NoSuchAlgorithmException | IOException | XmlParserException |
                 java.security.InvalidKeyException | ServerException e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 处理图片上传后外链地址
     * 只获得url端口号以后的内容
     * @param urlStr
     * @return
     */
    public String getImgUrl(String urlStr){
        if(urlStr.isEmpty()){
            return "";
        }
        Pattern pattern = Pattern.compile("\\?"); //通过正则找字符串中的?
        Matcher matcher = pattern.matcher(urlStr); //正则表达式比对器
        if (matcher.find()){
            int seartIndex = matcher.end();  //获得?开始的位置
            if(seartIndex!=-1){
                urlStr=urlStr.substring(0,seartIndex-1);
            }
        }
        Pattern pattern1 = Pattern.compile(":\\d{1,5}"); //通过正则找字符串中的端口
        Matcher matcher1 = pattern1.matcher(urlStr); //正则表达式比对器
        if (matcher1.find()){
            int endIndex = matcher1.end();  //获得正则表达式规则结束字符串的位置
            if(endIndex!=-1){
                return  urlStr.substring(endIndex);
            }
        }
        return "";
    }
}
